<template>
  <a-table :columns="columns" :data-source="data">
    <template #bodyCell="{column, text, record}">
      <template v-if="column.dataIndex === 'pattern'">
        <a-popover>
          <template #content>
            <a @click="() => showPatternDetail(record)">点击查看详情</a>
          </template>
          {{ text.substring(0, 80) }}...
        </a-popover>

      </template>
    </template>
  </a-table>
  <a-modal v-model:open="modalOpen" title="配置详情" width="1024px" @ok="closeModal">
    <p>名称: {{ modelDataItem.name }}</p>
    <div style="background-color: #ececec; padding: 20px">
      详情:
      <a-row :gutter="10">
        <a-col :span="12">
          <a-card :bordered="false" style="height: 400px; overflow-y: auto">
            <VueJsonPretty
                :data="JSON.parse(modelDataItem.pattern)"
                :style="{ height: '400px', overflowY: 'auto' }"/>
          </a-card>
        </a-col>
        <a-col :span="12">
          <a-card :bordered="false" title="DAG图" style="height: 400px">
            <div ref="dagContainer" style="width: 100%; height: 360px;"></div>
          </a-card>
        </a-col>
      </a-row>
    </div>
  </a-modal>
</template>

<script lang="ts" setup>
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
import { type EdgeOptions, Graph } from '@antv/g6';
import type { NodeOptions } from "@antv/g6/src/spec/element/node.ts";

defineProps<{ data: DataItem[] }>()

const modalOpen = ref<boolean>(false);

const modelDataItem = ref<DataItem>({})

const dagContainer = ref<HTMLElement | null>(null);
let graph: Graph = null;

const columns = [
  // {
  //   title: 'Key',
  //   dataIndex: 'key',
  //   key: 'key',
  //   width: '12%',
  // },
  {
    title: '名称',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '描述',
    dataIndex: 'desc',
    key: 'desc',
  },
  {
    title: '调用模式',
    dataIndex: 'pattern',
    key: 'pattern',
    width: '50%',
  },
  // {
  //   title: 'Source',
  //   dataIndex: 'source',
  //   key: 'source',
  // },
  // {
  //   title: 'Target',
  //   dataIndex: 'target',
  //   key: 'target',
  // },
  // {
  //   title: 'Svc-Source',
  //   dataIndex: 'svc_source',
  //   key: 'svc_source',
  // },
  // {
  //   title: 'Svc_Target',
  //   dataIndex: 'svc_target',
  //   key: 'svc_target',
  // },
];

interface DataItem {
  key: number;
  name: string;
  desc: string;
  pattern: string;
  // source: string;
  // svc_source: string;
  // target: string;
  // svc_target: string;
  // children?: DataItem[];
}


const rowSelection = ref({
  CheckStrictly: false,
  onChange: (selectedRowKeys: (string | number)[], selectedRows: DataItem[]) => {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  },
  onSelect: (record: DataItem, selected: boolean, selectedRows: DataItem[]) => {
    console.log(record, selected, selectedRows);
  },
  onSelectAll: (selected: boolean, selectedRows: DataItem[], changeRows: DataItem[]) => {
    console.log(selected, selectedRows, changeRows);
  },
});

const showPatternDetail = (record: DataItem) => {
  const pattern = JSON.parse(record.pattern);
  modelDataItem.value = record;
  openModel()
  // console.log('Pattern Detail:', pattern);
}


const openModel = () => {
  // 打开模态框
  modalOpen.value = true;
}

// 关闭模态框
const closeModal = () => {
  modalOpen.value = false;
}

const constructGraphData = (pattern: string) => {
  try {
    const parsedPattern = JSON.parse(pattern);
    console.log('解析模式数据:', parsedPattern);
    const nodes = parsedPattern.nodes.map((node: any) => ({
      id: node.id,
      data: {
        text: node.label,
      }
    }));
    const edges = parsedPattern.edges.map((edge: any) => ({
      source: edge.source,
      target: edge.target,
      label: edge.label, // 似乎没有用
    }));
    return { nodes, edges };
  } catch (e) {
    console.error('解析模式数据失败:', e);
    return { nodes: [], edges: [] };
  }
}


const renderDAG = () => {
  if (!dagContainer.value) return;

  try {
    // 如果之前已经创建了图表实例，先销毁它
    if (graph) {
      graph.destroy();
    }

    let { nodes, edges } = constructGraphData(modelDataItem.value.pattern);

    // 写死的测试数据
    const graphData = {
      nodes: nodes,
      edges: edges
    }

    // 创建G6图实例
    graph = new Graph({
      container: dagContainer.value,
      width: dagContainer.value.offsetWidth,
      data: graphData,
      height: 360,
      layout: {
        type: 'dagre',
        rankdir: 'LR', // 水平方向布局，从左到右
        nodesep: 60,
        ranksep: 80
      },
      node: <NodeOptions>{
        type: 'rect',
        style: {
          size: [120, 60],
          radius: 6,
          stroke: '#40a9ff',
          fill: '#e6f7ff',
          lineWidth: 2,
          labelPlacement: 'center',
          labelText: (d) => {
            let svc = d.data.text.split("~")[0];
            let route = d.data.text.split("~")[1];
            // "服务: xxx \n endpoint: xxx"
            return `服务: ${svc} \n 方法: ${route}`;
          },
          labelWordWrap: true,
          labelMaxLines: 2,
          labelMaxWidth: '90%',
          labelBackground: true,
          labelBackgroundFill: '#eee',
          labelBackgroundFillOpacity: 0.5,
          labelBackgroundRadius: 4,
          labelPointerEvents: 'none',
          labelBackgroundPointerEvents: 'none',
          // shadowColor: '#ccc',
          // shadowBlur: 10,
          // shadowOffsetX: 0,
          // shadowOffsetY: 0,
        }
      },
      edge: <EdgeOptions>{
        // type: 'polyline',
        style: {
          radius: 10,
          endArrow: true,
          lineWidth: 2,
          stroke: '#1890ff',
          labelText: (d) => {
            return d.label.split(' ')[0];
          },
          labelWordWrap: true,
          labelTextBaseline: 'bottom',
          labelDx: -8,
          labelFontSize: 12,
          labelFontWeight: 'bold',
          labelFill: '#1890ff',
          labelBackgroundStroke: '#9ec9ff',
          labelBackgroundRadius: 2,
        },
      },

      behaviors: ['drag-canvas', 'drag-element']
    });

    graph.render();

    // 自适应布局
    graph.fitView(20);
  } catch (error) {
    console.error('渲染DAG图出错：', error);
  }
};

// 监听窗口大小变化，重新渲染图表
const resizeHandler = () => {
  if (graph && dagContainer.value) {
    graph.changeSize(dagContainer.value.offsetWidth, 360);
    graph.fitView(20);
  }
};

// 监听modelDataItem的变化，重新渲染DAG图
watch(() => modalOpen.value, (newVal) => {
  if (newVal) {
    nextTick(() => {
      renderDAG();
    });
  }
});

onMounted(() => {
  window.addEventListener('resize', resizeHandler);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandler);
  if (graph) {
    graph.destroy();
  }
});

</script>

